我寫到現在,我一直覺得 golang 的 error 設計,一直讓人又愛又恨...,我們今天會分兩個面向來介紹它,一種是語言層面的 error ,也就是 panic,一種就是一般調用 func 所回傳的 error,改怎麼做整理...
語言層級的 panic 常常發生在,concurrency 時沒控制好資源,大致上有以下幾種情況
上述的三種錯誤都會直接讓 golang 直噴 panic,我自己帶我們家的 junior 時,都會交代一句話
他強任他強、清風拂山崗;他橫任他橫、明月照大江
他自狠來他自惡,我自一口真氣足
上面的話語引述自金庸的『倚天屠龍記』的『九陽真經』要領,意思就是,不管外界再怎麼狠毒,自身都不應該受到影響。我們寫 server 的人,可以因為 request 太多,暫時 pending 住,少收一些 request 但不能因為這樣整個 server 死掉。
下面為攔截 panic 錯誤的方式
package main
import (
"fmt"
)
func Excute() {
panic("wtf...")
}
func main() {
//defer 在這邊並沒有另外立章節介紹,在這邊簡單說明,他就是用在,這個func 結束前,你最後需要做什麼
//ex 有些o pen file的行為 最後需要 close 等等
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
Excute()
fmt.Println("end")
}
https://play.golang.org/p/82pg_A1epbe
前面就有講到 golang error 機制設計,我個人很喜歡,但也有一派人馬認為它會讓 code 看起來很瑣碎,因為它少掉了巢狀式 try catch ,這樣的好處在閱讀 source code,難易度大簡,但是換來的卻是
if err != nil {
return
}
寫到這裡,如果有稍微觀摩過一些 github 上的 golang pcakge,或是閱讀 golang source code,應該都不陌生上面這段 code。
之前去上海的 GopherChina2018 裡面有 golang 開發團隊的成員說,預計在
2.0
時,golang error handler 會有一個不小的修正。
在這邊要特別宣導一下,只要有看到 func 的回傳值有 error ,請一定要接出來,不要忽略它。以官方 net.Listen 套件為例
ln, err := net.Listen("tcp", ":8080")
if err != nil {
error handler ...
}
conn, err := ln.Accept()
如上,如果沒有讓它直接攔到,讓它持續往下執行,做了 ln.Accept()
,這時侯 ln 是 nil ,所以會觸發 nil of pointer,所以請大家不要嫌麻煩,任何錯誤都要接起來並且處理,可以省掉很多 debug 時間。